package bakudo.utils.performance.console {
	import bakudo.utils.performance.console.globals.InternalMessages;

	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.TextEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.utils.Dictionary;

	/**
	 * @author Micha� Rabi�ski
	 */
	public class TestersConsole extends Sprite {

		public var inputTf : TextField;
		public var historyTf : TextField;

		//::::::::::::::: private vars ::::::::::::::://
		private var consoleIsOn : Boolean;

		private var registeredObjects : Dictionary;

		public function TestersConsole() {
			registeredObjects = new Dictionary();
			addEventListener(Event.ADDED_TO_STAGE, onATS);
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PROTECTED METHODS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		protected function init() : void {
			inputTf = new TextField();
			inputTf.type = TextFieldType.INPUT;
			inputTf.autoSize = 'left';
			inputTf.multiline = true;
			inputTf.text = '';
			addChild(inputTf);
			//------------------------------------------------------------------
			
			//------------------------------------------------------------------
			consoleIsOn = false;
			turnConsoleOff();
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKD);			inputTf.addEventListener(TextEvent.TEXT_INPUT, onTextInput);
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PUBLIC METHODS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		public function turnConsoleOn() : void {
			trace('console is on');
			visible = true;
			stage.focus = inputTf;
		}

		public function turnConsoleOff() : void {
			trace('console is off');
			visible = false;
		}

		public function executeCommand(command : String) : void {
			var filteredCommand : String = checkTextForAvaliableCommand(command);
			if(filteredCommand == InternalMessages.COMMAND_NOT_FOUND) {
				trace('command not found');
			} else {
			}
		}

		/**
		 * Corelates given alias with given object
		 * Later on it's needed for recognition, because in inputTf we search 
		 * for avaliable aliases and operate on methods of object mapped to it
		 */
		public function registerObject(alias : String,object : Object) : void {
			registeredObjects[object] = alias;
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PRIVATE METHODS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		private function handleKeyDown(keycode : uint) : void {
			trace(keycode);
			switch(keycode) {
				case 192:
					switchConsoleState();
					break;
				case 13:
					executeCommand(inputTf.getLineText(inputTf.numLines - 1));
					break;
			}
		}

		private function handleTextInput(input : String) : void {
		}

		/**
		 * Switches console off/on, hides it or shows it.
		 */
		private function switchConsoleState() : void {
			if(!consoleIsOn)turnConsoleOn();
			else turnConsoleOff();
			consoleIsOn = !consoleIsOn;
		}

		private function checkTextForAvaliableCommand(command : String) : String {
			trace(command);
			var patt : RegExp;
			var obj : Object;
			for(var i in registeredObjects) {
				patt = new RegExp(registeredObjects[i] + "", "ig");
				if(patt.test(command)) {
					obj = i;
					break;
				}
			}
			if(!obj) return InternalMessages.COMMAND_NOT_FOUND;
			var firstSplit : Array = command.split(" ");
			var methodName : String = firstSplit[1];
			var parrams : Array = firstSplit.slice(2, firstSplit.length);
			
			trace('firstSplit', firstSplit);			trace('par1', methodName);			trace('parrams', parrams);
			
			
			
			
			trace('methodName_' + methodName + '_', 'innerParams_' + parrams + "_", parrams.length);
			if(parrams.length == 0)(obj[methodName] as Function)(); else {
				(obj[methodName] as Function)(parrams);
			}
			var comm : String;
			return comm;
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PRIVATE LISTENERS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		private function onATS(event : Event) : void {
			removeEventListener(Event.ADDED_TO_STAGE, onATS);
			init();
		}

		private function onKD(event : KeyboardEvent) : void {
			handleKeyDown(event.keyCode);
		}

		private function onTextInput(event : TextEvent) : void {
			handleTextInput(event.text);	
		}
	}	
}
